/**
 * Created by liyl on 24/09/2020.
 */
import io from 'socket.io-client'
import { Action, getModule, Module, Mutation, VuexModule } from 'vuex-module-decorators'
import store from '../../index'
import { ctiEventHandler } from '../cti/ctiEvent'
import { WebchatEventModule } from '@/store/modules/webchat/webchatSocketEvent'
import { IvrModule } from '@/store/modules/config/ivr'
import { MessageBox } from 'element-ui'
import { kickMessage } from '@/utils/messageCustom'
import { CommonModule } from '@/store/modules/common'
import { WebchatModule } from '@/store/modules/webchat'
import { MessageModule } from '../message/sysMsg'
import { toRawType, storageManager } from '@/utils/common'
import router from '@/router/handleRoute'
import { instance } from '@/microPage/webchat/main'
import { businessStore } from '@/afterSales/views/business/store/business'
export interface SocketState {
  isLogin: any
  lastSocketId: any
}
@Module({ dynamic: true, name: 'socketIo', store, namespaced: false })
class Socket extends VuexModule implements SocketState {
  public isLogin: any
  public lastSocketId: any = null

  @Action
  public async initSocket (sessionData: any) {
    let localForm = storageManager.get('loginForm')
    localForm = localForm && localForm !== 'undefined' && localForm !== 'null' ? JSON.parse(localForm) : {}
    const queryData = {
      token: sessionData.data.user.stoken,
      userId: sessionData.data.user._id,
      agentNumber: sessionData.data.user.agentNumber,
      accountId: sessionData.data.user.accountId,
      loginType: localForm.loginType
    }
    this.isLogin = sessionData.isLogin
    const emitData = {
      userId: sessionData.data.user._id,
      loginType: localForm.loginType,
      loginStatus: [{ loginModule: 'call', loginNumber: '' }] // loginModule登录模块  loginNumber  登录状态编号
    }
    const socketData = { reconnectionDelay: 3000, query: queryData }
    socketData['force new connection'] = true
    const pushObj = store.state.common.initConfig.pushServer || {}
    let pushUrl = pushObj.url
    if (window.location.host.indexOf('localhost') > -1) { // 本地代理https环境还是http环境，自己修改
      pushUrl = `wss://${pushUrl}`
    }
    const containerType = store.state.common.containerType
    if (containerType && containerType === 'micro') { // cep 用登录返回的socket地址
      pushUrl = store.state.common.session.extras.sdkUrl + '/' + store.state.common.session.extras.namespace
    }
    if (!pushUrl) {
      return false
    }
    const socket = io.connect(pushUrl, socketData)
    socket.on('connect_error', () => {
      console.log('connect_error')
    })
    socket.on('connect', () => {
      if (this.lastSocketId !== null) { // 断网重连
        offlineMessage() // 断线重连之后要重新获取在线列表
      }
    })
    socket.on('socketId', (data: any) => {
      this.SET_LASTSOCKETID(data.socketId)
      if (this.isLogin) { // 是普通登录
        emitData.loginStatus[0].loginNumber = localForm.loginStatus ? '0' : '1'
        this.isLogin = false
      } else { // 刷新系统或者是断网重连
        emitData.loginStatus[0].loginNumber = ''
      }
      const isKick = (data.result && data.result.data && data.result.data.isKick) || false
      const callConfig: any = store.state.common.session.extra ? store.state.common.session.extra.callConfig : {}
      if ((containerType && containerType === 'micro') || (callConfig && !callConfig.isPushOnline)) { // 微前端不发通话的登录请求 || 非通话版本的座席
        webchatStatusFun(isKick)
      } else {
        CommonModule.publicAction({ url: '/auth/action/pushOnline', method: 'POST', data: emitData, hideLoading: true })
        // 只有在线状态领取开关权限才去通知后端去分配
        webchatStatusFun(isKick)
      }
    })
    socket.on('error', (data: any) => {
      console.log('push connection error' + JSON.stringify(data))
    })
    socket.on('commonEvent', (data, fn) => { // 通用事件
      // 回给服务器进行确认
      if (fn && typeof fn === 'function') {
        fn('success')
      }
      if (data.type === 'SOCKET_SALE_SIGN') {
        const { body } = data
        businessStore.signObj = body
      }
      if (data.type === 'kickOff') { // 踢出
        MessageBox.alert('您当前的会话已经失效,导致该问题的原因是别的座席使用相同的帐号（或相同的分机）登录了', '提示', {
          confirmButtonText: '确定',
          type: 'warning',
          callback: action => {
            if (store.state.common.containerType && store.state.common.containerType === 'micro') { // 如果是微前端加载用微前端的实例
              const microStore = (instance.$root as any).microStore
              if (microStore) {
                microStore.kickOff()
              }
            }
            CommonModule.setIsSignOut() // 主动退出的标识，用于onbeforeunload的时候，不提醒
            router.push({ path: '/login' })
            window.location.reload()
          }
        })
        socket.disconnect()
      }
      if (data.type === 'kickOff_licence_stop') { // 座席使用中，当前座席的版本停用了
        kickMessage(5)
      }
      if (data.type === 'envChange') {
        const ele: any = document.getElementById('versionTip');
        const element: any = document.getElementById('versionTipText');
        if (data.body.text) {
          element.innerText = data.body.text;
        }
        ele.style.display = 'block';
      }
      if (data.type === 'messageEvent') { // 右上角 小铃铛 消息推送
        if (data.body.remindWay && toRawType(data.body.remindWay) === 'Array') {
          // 触达方式：系统，小红点，增加未读数
          if (data.body.remindWay.includes('system')) {
            MessageModule.ADD_ALL_NO_READ_COUNT()
          }
          // 触达方式：浏览器，弹屏提醒
          if (data.body.remindWay.includes('browser')) {
            // 浏览器消息提示
            if (data.body.type === 'mpNotice') {
              const mpData = data.body.data || {}
              const params = { url: '/crm/action/template/query', method: 'POST', data: { worksheetId: mpData.worksheetId } }
              CommonModule.publicAction(params).then(resp => {
                if (resp.success) {
                  if (resp.data) {
                    const routeData = { recordId: mpData.recordId, viewId: mpData.viewId, worksheetId: mpData.worksheetId }
                    const notifyData = { bodyType: 'mpNotice', type: resp.data.type, name: resp.data.name, data: data.body.data }
                    const routeUrl = resp.data.type === 'CUSTOMER' ? `/crm_workBench/index?mpData=${JSON.stringify(routeData)}` : `/ticket_workBench/index?mpData=${JSON.stringify(routeData)}`
                    CommonModule.NOTIFY({
                      title: data.body.name,
                      message: data.body.content,
                      options: {
                        dir: 'auto',
                        icon: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=405069346,3880007726&fm=11&gp=0.jpg',
                        body: data.body.content || ''
                      },
                      routePath: routeUrl,
                      notifyData
                    })
                  }
                }
              })
            } else {
              CommonModule.NOTIFY({
                title: data.body.name,
                message: data.body.content,
                options: {
                  dir: 'auto',
                  icon: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=405069346,3880007726&fm=11&gp=0.jpg',
                  body: ''
                },
                routePath: data.body.type === 'notice' ? '/home/index' : '',
                notifyData: {}
              })
            }
          }
        }
      }
    })
    socket.on('callEvent', (data, fn) => { // 通话事件
      if (fn && typeof fn === 'function') {
        fn('success')
      }
      ctiEventHandler(data) // 通话事件分发
    })
    socket.on('imEvent', (data, fn) => { // 在线事件
      if (fn && typeof fn === 'function') {
        fn('success')
      }
      WebchatEventModule.handleWebchatEvent(data)
    })
    socket.on('qiniu', (data, fn) => { // 七牛事件
      if (fn && typeof fn === 'function') {
        fn('success')
      }
      if (data.type === 'qiniuTransferNotify') { // 语音库，MP3七牛转换成wav
        IvrModule.setVoiceTransfer(data.body || '')
      }
    })

    // 关闭事件时，调用socket的disconnect
    if (window.addEventListener) {
      window.addEventListener('close', () => {
        io.disconnect()
      })
    } else {
      (window as any).attachEvent('onclose', () => {
        io.disconnect()
      })
    }
    const offlineMessage = () => { // 获取在线会话列表
      const sendData = {
        submenu: 'webchat_todo'
      }
      const actionData = { url: '/im-center/action/webchat/queryWebchatSession', method: 'POST', data: sendData }
      WebchatModule.getWebchatList(actionData)
    }

    const webchatStatusFun = (isKick) => { // 在线登录
      const session: any = CommonModule.session
      const limit: any = session.user.limits ? session.user.limits : []
      const webchatStatusData = storageManager.get('webchatStatus') ? JSON.parse(storageManager.get('webchatStatus')) : sessionData.webchatStatus
      if (limit.indexOf('im_change') > -1 && webchatStatusData) {
        const webchatStatusActionData = {
          url: '/im-center/action/webchat/imSocketLogin',
          method: 'POST',
          data: { status: webchatStatusData.status, _id: webchatStatusData._id, isKick, socketId: this.lastSocketId }
        } // 在线登录状态
        CommonModule.publicAction(webchatStatusActionData).then(res => {
          if (res && res.success) {
            WebchatModule.SET_WEBCHAT_UNDEALNUM(res.queueCount || 0)
          }
        })
      }
    }
  }

  @Mutation
  public async SET_LASTSOCKETID (data: any) {
    this.lastSocketId = data
  }
}
export const SocketModule = getModule(Socket)
